/* MEM @ 500Mhz */
/* GPU @ 400Mhz */
#define DDR_REFC   4
#define DDR_DIV    1
#if (DDR_CLOCK_RATE == 500000000)
#define DDR_DIV_L2 6
#else
#define DDR_DIV_L2 4
#endif
#define GPU_DIV_L2 0x3f

#define PLL_IN     OSC_CLK
#define DDR_LOOPC  ((DDR_CLOCK_RATE*DDR_DIV_L2*DDR_REFC)/(PLL_IN))
#define HDA_DIV_L2 (((PLL_IN)*DDR_LOOPC)/(DDR_REFC*24000000))

/* CPU @ 1000Mhz */
#define L1_REFC    1
#define L1_DIV     1

#define L2_REFC    L1_REFC
#define L2_DIV     2

#define L1_LOOPC   ((CPU_CLOCK_RATE*L2_DIV*L1_REFC)/(PLL_IN))
#define L2_LOOPC   L1_LOOPC


/* DC @ 250Mhz */
/* GMAC @ 125Mhz */
#define DC_LOOPC   10
#define DC_REFC    1
#define DC_DIV     1
#define DC_DIV_L2  4
#define GMAC_DIV   8

#define PIX0_LOOPC  10
#define PIX0_REFC   1
#define PIX0_DIV    1
#define PIX0_DIV_L2 8

#define PIX1_LOOPC  10
#define PIX1_REFC   1
#define PIX1_DIV    1
#define PIX1_DIV_L2 8

#define PLL_CHANG_COMMIT 0x1

#define PLL_L1_LOCKED  (0x1 << 16)
#define PLL_L1_ENA     (0x1 << 2)
#define PLL_MEM_LOCKED (0x1 << 16)
#define PLL_MEM_ENA    (0x1 << 2)

#define SATA_FREQSCALE 0x7

ls2k_clk_config:

	TTYDBG ("\r\nsoft clk config\r\n")

	TTYDBG ("NODE:")

	li  t0, 0xbfe10480
	li  t1, (0x1 << 19) 	//power down pll L1 first
	sd  t1, 0x0(t0)
	dli t1, (L2_LOOPC << 54) | (L2_REFC  << 48) | (L1_DIV << 42) | (L1_LOOPC << 32) | (L1_REFC << 26) | (0x3 << 10) | (0x1 << 7)
	dli t2, L2_DIV
	sd  t1, 0(t0)
	sd  t2, 8(t0)
	ori t1, PLL_L1_ENA
	sd  t1, 0x0(t0)
	//freqscale
	li  t2, 0xbfe104d0
	ld  a0, 0x0(t2)
	li  t1, 0xff8fffff
	and a0, t1, a0
	or  a0, a0, (APB_FREQSCALE << 20) | (7 << 16) | (SATA_FREQSCALE << 12) | (7 << 8) | (7 << 0)//设置APB分频配置
	sd  a0, 0x0(t2)

11:
	ld   a0, 0x0(t0)
	li   a1, PLL_L1_LOCKED
	and  a0, a1, a0
	beqz a0, 11b //wait_locked_sys
	nop

	ld   a0, 0x0(t0)
	ori  a0, a0, PLL_CHANG_COMMIT
	sd   a0, 0x0(t0)
	bal  hexserial
	nop

	TTYDBG ("\r\nDDR:")

	li   t0, 0xbfe10490
	li   t1, (0x1 << 19) 	//power down pll  first
	sd   t1, 0x0(t0)
	dli  t1, (DDR_DIV << 42) | (DDR_LOOPC << 32) | (DDR_REFC << 26) | (0x3 << 10) | (0x1 << 7)
	dli  t2, (HDA_DIV_L2 << 44) | (GPU_DIV_L2 << 22) | (DDR_DIV_L2)
	sd   t1, 0x0(t0)
	sd   t2, 0x8(t0)
	ori  t1, PLL_L1_ENA
	sd   t1, 0x0(t0)

21:
	lw   a0, 0x0(t0)
	li   a1, PLL_MEM_LOCKED
	and  a0, a0, a1
	beqz a0, 21b //wait_locked_ddr
	nop

	lw   a0, 0x0(t0)
	ori  a0, a0, 0x3
	sw   a0, 0x0(t0)
	bal  hexserial
	nop

	TTYDBG ("\r\nDC:")

	li   t0, 0xbfe104a0
	li   t1, (0x1 << 19) 	//power down pll  first
	sd   t1, 0x0(t0)
	dli  t1, (DC_DIV << 42) | (DC_LOOPC << 32) | (DC_REFC << 26) | (0x3 << 10) | (0x1 << 7)
	dli  t2, (GMAC_DIV << 22) | (DC_DIV_L2)
	sd   t1, 0x0(t0)
	sd   t2, 0x8(t0)
	ori  t1, PLL_L1_ENA
	sd   t1, 0x0(t0)

21:
	lw   a0, 0x0(t0)
	li   a1, PLL_MEM_LOCKED
	and  a0, a0, a1
	beqz a0, 21b
	nop

	//apb频率改变后再次初始化调试串口，apb频率通过gmac频率分频出来，默认125MHz
	li  a0, (APB_CLOCK_RATE/16)/CONFIG_BAUDRATE
	bal initserial
	nop

	li   t0, 0xbfe104a0
	lw   a0, 0x0(t0)
	ori  a0, a0, 0x3
	sw   a0, 0x0(t0)
	bal  hexserial
	nop

	TTYDBG ("\r\nPIX0:")

	li   t0, 0xbfe104b0		//pll_pix0
	li   t1, (0x1 << 19) 	//power down pll  first
	sd   t1, 0x0(t0)
	dli  t1, (PIX0_DIV << 42) | (PIX0_LOOPC << 32) | (PIX0_REFC << 26) | (0x3 << 10) | (0x1 << 7)
	dli  t2, PIX0_DIV_L2
	sd   t1, 0x0(t0)
	sd   t2, 0x8(t0)
	ori  t1, PLL_L1_ENA
	sd   t1, 0x0(t0)

21:
	lw   a0, 0x0(t0)
	li   a1, PLL_MEM_LOCKED
	and  a0, a0, a1
	beqz a0, 21b
	nop

	lw   a0, 0x0(t0)
	ori  a0, a0, 0x1
	sw   a0, 0x0(t0)
	bal  hexserial
	nop

	TTYDBG ("\r\nPIX1:")

	li   t0, 0xbfe104c0		//pll_pix1
	li   t1, (0x1 << 19) 	//power down pll  first
	sd   t1, 0x0(t0)
	dli  t1, (PIX1_DIV << 42) | (PIX1_LOOPC << 32) | (PIX1_REFC << 26) | (0x3 << 10) | (0x1 << 7)
	dli  t2, PIX1_DIV_L2
	sd   t1, 0x0(t0)
	sd   t2, 0x8(t0)
	ori  t1, PLL_L1_ENA
	sd   t1, 0x0(t0)

21:
	lw   a0, 0x0(t0)
	li   a1, PLL_MEM_LOCKED
	and  a0, a0, a1
	beqz a0, 21b
	nop

	li   t0, 0xbfe104d0		//freq_scale
	dli  t1, (1 << 33) | (1 << 32) | (APB_FREQSCALE << 20) | (7 << 16) | (SATA_FREQSCALE << 12) | (7 << 8) | (7 << 0)
	sd   t1, 0x0(t0)

	lw   a0, 0x0(t0)
	ori  a0, a0, 0x1
	sw   a0, 0x0(t0)
	bal  hexserial
	nop

	li    a0, 0x4000
31:
	addiu a0, -1
	nop
	bnez  a0, 31b
	nop
